#! /usr/bin/python3
# _*_ coding:UTF-8 _*_
import time
import functools


def now():
    print(time.strftime('%Y-%m-%d %H:%M:%S'))


# ，因为它是一个decorator，所以接受一个函数作为参数，并返回一个函数
def log1(func):
    def wrapper(*args, **kw):
        print('call {}():'.format(func.__name__))
        return func(*args, **kw)
    return wrapper


# 装饰器需要传入参数
def log2(test):
    def decorator(func):
        def wrapper(*args, **kw):
            print('真是装饰器文本:', test)
            print('call {}():'.format(func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator


# 把原始被装饰的函数的原始属性传入装饰函数
# @functools.wraps(func) 相当于wrapper.__name__ = func.__name__
def log3(func):
    @functools.wraps(func)  # 把func的 __name__ 属性 传给下面的函数
    def wrapper(*args, **kw):
        print('call %s()' % func.__name__)
        return func(*args, **kw)
    return wrapper


def log4(test):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('真是装饰器文本:', test)
            print('call {}():'.format(func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator


@log1   # 相当于now2 = log(now2) 新now2指向wrapper 调用时 执行wrapper() 先进行打印 在执行反回原now2()
def now1(n1):
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    print('这个函数是{}'.format(now1.__name__))   # 此时now3 已经指向wrapper, 因此__name__ 属性是wrapper
    print(n1)


@log2('装饰器参数1 now2')
def now2(n2):
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    print('这个函数是{}'.format(now2.__name__))   # 此时now2 已经指向wrapper, 因此__name__ 属性是wrapper
    print(n2)


@log3
def now3(n3):
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    print('这个函数是{}'.format(now3.__name__))   # 此时now3 已经指向wrapper, 但wrapper的属性已经复制func的属性因此__name__ 属性是'now3'
    print(n3)


@log4('装饰器参数4 now4')
def now4(n4):
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    print('这个函数是{}'.format(now4.__name__))   # 此时now4 已经指向wrapper, 但wrapper的属性已经复制func的属性因此__name__ 属性是'now4'
    print(n4)


if __name__ == '__main__':
    f = now
    f()
    print(now.__name__)
    print(f.__name__)
    print('********* 装饰器********')
    # 装饰器
    n1 = '这是now1'
    now1(n1)
    print('*********带参数的装饰器********')
    # 带参数的装饰器
    n2 = '这是now2'
    now2(n2)
    print('*******带有没有参数的属性复制的装饰器*******')
    # 带有没有参数的属性复制的装饰器
    n3 = '这是now3'
    now3(n3)
    print('*******带有复制属性的 有参数的装饰器*******')
    # 带有复制属性的 有参数的装饰器
    n4 = '这是now4'
    now4(n4)
